package cn.kgc.service.impl;

import cn.kgc.client.SmsSpuFeignClient;
import cn.kgc.client.WmsWareSkuFeignClient;

import cn.kgc.commons.exception.HttpException;
import cn.kgc.commons.vo.Result;
import cn.kgc.constant.PmsSpuDefaultImage;
import cn.kgc.constant.PmsSpuStatus;
import cn.kgc.dto.*;
import cn.kgc.dto.add.*;
import cn.kgc.entity.*;
import cn.kgc.mapper.*;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.kgc.service.PmsSpuInfoService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * spu信息(PmsSpuInfo)表服务实现类
 *
 * @author makejava
 * @since 2022-12-05 09:39:26
 */
@Service("pmsSpuInfoService")
@Slf4j
public class PmsSpuInfoServiceImpl extends ServiceImpl<PmsSpuInfoMapper, PmsSpuInfo> implements PmsSpuInfoService {

    @Override
    public SpuItemVO selectById(Long skuId) {
        SpuItemVO spuItemVO=new SpuItemVO();
        //1 商品的基本信息(skuInfo)
        CompletableFuture<PmsSkuInfo> pmsSkuInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
            PmsSkuInfo pmsSkuInfo = pmsSkuInfoMapper.selectById(skuId);

            spuItemVO.setPmsSkuInfo(pmsSkuInfo);

            Long brandId = pmsSkuInfo.getBrandId();
            PmsBrand pmsBrand = pmsBrandMapper.selectById(brandId);
            pmsSkuInfo.setBrandName(pmsBrand.getName());

            Long catalogId = pmsSkuInfo.getCatalogId();
            PmsCategory pmsCategory = pmsCategoryMapper.selectById(catalogId);
            pmsSkuInfo.setCategoryName(pmsCategory.getName());

            Long spuId = pmsSkuInfo.getSpuId();
            PmsSpuInfo pmsSpuInfo = pmsSpuInfoMapper.selectById(spuId);
            pmsSkuInfo.setSpuName(pmsSpuInfo.getSpuName());

            return pmsSkuInfo;
        }, threadPoolExecutor);


        //2 商品的图片信息
        CompletableFuture<Void> pmsSkuImagesCompletableFuture = CompletableFuture.runAsync(() -> {
            LambdaQueryWrapper<PmsSkuImages> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(PmsSkuImages::getSkuId, skuId);
            List<PmsSkuImages> pmsSkuImagesList = pmsSkuImagesMapper.selectList(lambdaQueryWrapper);
            spuItemVO.setImagesList(pmsSkuImagesList);
        }, threadPoolExecutor);

        //3 商品的销售属性
        CompletableFuture<Void> pmsSkuSaleAttrValueCompletableFuture = CompletableFuture.runAsync(() -> {
            LambdaQueryWrapper<PmsSkuSaleAttrValue> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(PmsSkuSaleAttrValue::getSkuId, skuId);
            List<PmsSkuSaleAttrValue> pmsSkuSaleAttrValueList =
                    pmsSkuSaleAttrValueMapper.selectList(lambdaQueryWrapper);

            List<Attr> attrList = pmsSkuSaleAttrValueList.stream().map(pmsSkuSaleAttrValue -> {
                Attr attr = new Attr();
                BeanUtils.copyProperties(pmsSkuSaleAttrValue, attr);
                return attr;
            }).collect(Collectors.toList());
            spuItemVO.setPmsSkuItemSaleAttrVoList(attrList);
        }, threadPoolExecutor);

        //4 获得SPU的介绍信息,通过spu的ID获得介绍信息
        CompletableFuture<Void> pmsSkuInfoDescCompletableFuture = pmsSkuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
            Long spuId = skuInfo.getSpuId();
            PmsSpuInfoDesc pmsSpuInfoDesc = pmsSpuInfoDescMapper.selectById(spuId);
            spuItemVO.setPmsSpuInfoDesc(pmsSpuInfoDesc);
        },threadPoolExecutor);

        //5查询属性组的信息
        CompletableFuture<Void> pmsAttrGroupCompletableFuture =
                pmsSkuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
                    //商品基本信息对应的分类的ID
                    Long catalogId = skuInfo.getCatalogId();
                    //最终商品属性组的集合
                    List<SpuItemVO.PmsSpuItemGroupAttrVo> pmsSpuItemGroupAttrVoList
                            = new ArrayList<>();
                    //根据商品分类的ID查询属性组的信息
                    LambdaQueryWrapper<PmsAttrGroup>lambdaQueryWrapper=new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(PmsAttrGroup::getCatelogId,catalogId);
                    List<PmsAttrGroup> pmsAttrGroups = pmsAttrGroupMapper.selectList(lambdaQueryWrapper);

                    //遍历属性组的集合
                    for (PmsAttrGroup pmsAttrGroup : pmsAttrGroups) {

                        SpuItemVO.PmsSpuItemGroupAttrVo pmsSpuItemGroupAttrVo =
                                new SpuItemVO.PmsSpuItemGroupAttrVo();

                        //获得属性组的名字
                        String attrGroupName = pmsAttrGroup.getAttrGroupName();
                        pmsSpuItemGroupAttrVo.setGroupName(attrGroupName);

                        //获得属性组所对应的基本属性信息
                        //1 通过属性组的ID，获得属性组与属性关联关系的集合
                        Long attrGroupId = pmsAttrGroup.getId();
                        LambdaQueryWrapper<PmsAttrAttrgroupRelation> lambdaQueryWrapper2=new LambdaQueryWrapper<>();
                        lambdaQueryWrapper2.eq(PmsAttrAttrgroupRelation::getAttrGroupId,attrGroupId);
                        List<PmsAttrAttrgroupRelation> pmsAttrAttrGroupRelationsList =
                                pmsAttrAttrgroupRelationMapper.selectList(lambdaQueryWrapper2);
                        //属性组对应的基本属性集合
                        List<Attr> baseAttrList=new ArrayList<>();
                        //2 通过属性组和属性关联关系，获得关联的属性的ID，获得属性所对应的属性的信息
                        for (PmsAttrAttrgroupRelation pmsAttrAttrgroupRelation : pmsAttrAttrGroupRelationsList) {
                            Long attrId = pmsAttrAttrgroupRelation.getAttrId();
                            //3 通过属性的ID和商品的ID 去商品的属性表中获得基本的属性信息
                            LambdaQueryWrapper<PmsProductAttrValue> lambdaQueryWrapper3=new LambdaQueryWrapper<>();
                            lambdaQueryWrapper3.eq(PmsProductAttrValue::getAttrId,attrId);
                            lambdaQueryWrapper3.eq(PmsProductAttrValue::getSpuId,skuInfo.getSpuId());
                            //获得属性的信息
                            PmsProductAttrValue pmsProductAttrValue =
                                    pmsProductAttrValueMapper.selectOne(lambdaQueryWrapper3);
                            Attr attr=new Attr();
                            BeanUtils.copyProperties(pmsProductAttrValue,attr);
                            baseAttrList.add(attr);
                        }
                        pmsSpuItemGroupAttrVo.setBaseAttrs(baseAttrList);
                        pmsSpuItemGroupAttrVoList.add(pmsSpuItemGroupAttrVo);
                    }
                    //将属性组的信息放入到商品的基本信息中
                    spuItemVO.setPmsSpuItemGroupAttrVo(pmsSpuItemGroupAttrVoList);
                }, threadPoolExecutor);
            //等待所有的异步任务都执行完毕以后，在向下执行
        CompletableFuture.allOf( //等这4个任务执行完，pmsSkuInfoDescCompletableFuture以来第一个任务执行完才能执行，所以allof放4个任务
                pmsSkuInfoDescCompletableFuture,
                pmsAttrGroupCompletableFuture,
                pmsSkuSaleAttrValueCompletableFuture,
                pmsSkuImagesCompletableFuture
        ).join();
        return spuItemVO;
    }










    @Override
    @Transactional
    public boolean up(Long spuId) {
        log.info("商品上架：spuId:{}",spuId);
        //实现商品的上下架功能
        updateSpuStatus(spuId,PmsSpuStatus.PUBLISH.getStatus());
        //2 收集商品对应的SKU信息
        List<SkuEsModel> skuEsModelList = getSkuEsModel(spuId);
        System.out.println(JSON.toJSONString(skuEsModelList));
        //3 将sku信息保存到ES中
        for (SkuEsModel skuEsModel : skuEsModelList) {
            skuEsModelElasticsearchRepository.save(skuEsModel);
        }

        return true;
    }


    private List<SkuEsModel> getSkuEsModel(Long spuId) {
        List<SkuEsModel> skuEsModelList = new ArrayList<>();
        LambdaQueryWrapper<PmsSkuInfo>lambdaQueryWrapper=new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PmsSkuInfo::getSpuId,spuId);
        List<PmsSkuInfo> pmsSkuInfoList =
                pmsSkuInfoMapper.selectList(lambdaQueryWrapper);
        //每个sku对应的都是一个ES中的SkuEsModel对象
        for (PmsSkuInfo pmsSkuInfo : pmsSkuInfoList) {
              //1 查询sku信息
            SkuEsModel skuEsModel=new SkuEsModel(); //一个ES中的SKU对象
            skuEsModel.setSpuId(spuId); //spuId
            skuEsModel.setSkuId(pmsSkuInfo.getId());  //SKU的ID
            skuEsModel.setSubTitle(pmsSkuInfo.getSkuSubtitle()); //二级标题
            skuEsModel.setSkuPrice(pmsSkuInfo.getPrice()); //价格
            skuEsModel.setSkuImg(pmsSkuInfo.getSkuDefaultImg()); //默认图片
            skuEsModel.setSaleCount(pmsSkuInfo.getSaleCount()); //销量
            skuEsModel.setBrandId(pmsSkuInfo.getBrandId()); //品牌ID
            skuEsModel.setCategoryId(pmsSkuInfo.getCatalogId());
//            skuEsModel.setCategoryName(pmsSkuInfo.getCategoryName());
//            品牌的名字
            PmsBrand pmsBrand =
                    pmsBrandMapper.selectById(pmsSkuInfo.getBrandId());
            if (pmsBrand!=null){
                // 品牌的名字
                skuEsModel.setBrandName(pmsBrand.getName());
                //品牌图片
                skuEsModel.setBrandImg(pmsBrand.getLogo());
            }
            getSkuAttrValue(pmsSkuInfo,skuEsModel);
            //是否还有库存

            Boolean hasStock =
                    wmsWareSkuFeignClient.hasStock(pmsSkuInfo.getId()).getData();
            skuEsModel.setHasStock(hasStock);
            skuEsModelList.add(skuEsModel);
        }
        return skuEsModelList;
    }

    //抽出的方法
    private void getSkuAttrValue(PmsSkuInfo pmsSkuInfo,SkuEsModel skuEsModel) {
        LambdaQueryWrapper<PmsSkuSaleAttrValue>pmsSkuSaleAttrValueLambdaQueryWrapper=
                new LambdaQueryWrapper<>();
        pmsSkuSaleAttrValueLambdaQueryWrapper.eq(PmsSkuSaleAttrValue::getSkuId, pmsSkuInfo.getId());
        List<PmsSkuSaleAttrValue> pmsSkuSaleAttrValueList =
                pmsSkuSaleAttrValueMapper.selectList(pmsSkuSaleAttrValueLambdaQueryWrapper);
        List<SkuEsModel.Attrs>attrsList=new ArrayList<>();
        for (PmsSkuSaleAttrValue pmsSkuSaleAttrValue : pmsSkuSaleAttrValueList) {
            SkuEsModel.Attrs attr=new SkuEsModel.Attrs();
            BeanUtils.copyProperties(pmsSkuSaleAttrValue,attr);
            attrsList.add(attr);
        }
        skuEsModel.setAttrList(attrsList);
    }


    //抽出方法

    /**
     * 实现商品的上下架功能
     * @param spuId  商品的ID
     * @param status  商品要修改的状态（上架和下架）
     */
    private void updateSpuStatus(Long spuId,int status) {
        PmsSpuInfo  pmsSpuInfo=pmsSpuInfoMapper.selectById(spuId);
        if(pmsSpuInfo==null){
            throw new HttpException(20004,HttpStatus.INTERNAL_SERVER_ERROR.value());
        }
        if(pmsSpuInfo.getPublishStatus()== status){  //修改的状态和原有的状态一样
            if (status == PmsSpuStatus.PUBLISH.getStatus()) {
                throw new HttpException(20005,HttpStatus.INTERNAL_SERVER_ERROR.value());
            } else {
                throw new HttpException(20006,HttpStatus.INTERNAL_SERVER_ERROR.value());
            }

        }
        pmsSpuInfo.setPublishStatus((short) PmsSpuStatus.PUBLISH.getStatus());
        pmsSpuInfoMapper.updateById(pmsSpuInfo);
    }

    @Override
    public boolean down(Long spuId) {
        return false;
    }

    @Resource
    private PmsSpuInfoMapper pmsSpuInfoMapper;
    @Resource
    private PmsSpuInfoDescMapper pmsSpuInfoDescMapper;
    @Resource
    private PmsSpuImagesMapper pmsSpuImagesMapper;
    @Resource
    private PmsProductAttrValueMapper pmsProductAttrValueMapper;
    @Resource
    private PmsAttrMapper pmsAttrMapper;
    @Resource
    private PmsSkuInfoMapper pmsSkuInfoMapper;
    @Resource
    private PmsSkuImagesMapper pmsSkuImagesMapper;
    @Resource
    private PmsSkuSaleAttrValueMapper pmsSkuSaleAttrValueMapper;

    @Resource
    private PmsBrandMapper pmsBrandMapper;

    @Resource
    private SmsSpuFeignClient smsSpuFeignClient;

    @Resource
    private WmsWareSkuFeignClient wmsWareSkuFeignClient;

    @Resource
    private SkuEsModelElasticsearchRepository skuEsModelElasticsearchRepository;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @Resource
    private PmsCategoryMapper pmsCategoryMapper;

    @Resource
    private PmsAttrGroupMapper pmsAttrGroupMapper; //属性组分组

    @Resource
    private PmsAttrAttrgroupRelationMapper   pmsAttrAttrgroupRelationMapper;  //属性和属性组关联的mapper




    @GlobalTransactional
    public boolean savePmsSpuInfo(SpuInfoVO spuInfoVO) {
        //1 新增sku信息
        PmsSpuInfo pmsSpuInfo = new PmsSpuInfo();
        BeanUtils.copyProperties(spuInfoVO, pmsSpuInfo);
        pmsSpuInfoMapper.insert(pmsSpuInfo);

        //2 pms_spu_info_desc
        List<String> decriptList = spuInfoVO.getDecript();
        PmsSpuInfoDesc pmsSpuInfoDesc = new PmsSpuInfoDesc();
        pmsSpuInfoDesc.setId(pmsSpuInfo.getId());
        String desc = "";
        for (String s : decriptList) {
            desc += s + ";";
        }
        pmsSpuInfoDesc.setDecript(desc);
        pmsSpuInfoDescMapper.insert(pmsSpuInfoDesc);

        //pms_spu_images 商品图片信息
        List<String> images = spuInfoVO.getImages();
        int count = 0;
        for (String s : images) {
            PmsSpuImages pmsSpuImages = new PmsSpuImages(); //商品的图片信息
            pmsSpuImages.setImgName(s);

                pmsSpuImages.setDefaultImg(PmsSpuDefaultImage.DEFAULT_IMAGE.getDefaultImage());


            //   pmsSpuImages.setDefaultImg();  是否是默认图片
            pmsSpuImages.setImgUrl(s);
            pmsSpuImagesMapper.insert(pmsSpuImages);
            count++;
        }

        List<BaseAttrs> baseAttrsList = spuInfoVO.getBaseAttrs();

        PmsProductAttrValue pmsProductAttrValue = new PmsProductAttrValue();
        for (BaseAttrs baseAttrs : baseAttrsList) {
            //基础属性的id
            pmsProductAttrValue.setAttrId(baseAttrs.getAttrId());
            PmsAttr pmsAttr = pmsAttrMapper.selectById(baseAttrs.getAttrId());
            //基础属性的名字
            pmsProductAttrValue.setAttrName(pmsAttr.getAttrName());
            //基础属性的值
            pmsProductAttrValue.setAttrValue(baseAttrs.getAttrValues());
            //基础属性的商品id
            pmsProductAttrValue.setSpuId(pmsSpuInfo.getId());
            //基础属性的排序规则
            pmsProductAttrValue.setAttrSort(baseAttrs.getShowDesc());
            //基础属性的快速展示
            pmsProductAttrValue.setQuickShow(baseAttrs.getQuickShow());
            pmsProductAttrValueMapper.insert(pmsProductAttrValue);
        }

        //pms_sku_info商品信息
        //新增商品的sku的信息
        List<Skus> skusList = spuInfoVO.getSkus(); //获取商品的sku的信息
        PmsSkuImages pmsSkuImages = new PmsSkuImages(); //sku的图片信息
        PmsSkuInfo pmsSkuInfo = new PmsSkuInfo(); //商品的sku信息
        PmsSkuSaleAttrValue pmsSkuSaleAttrValue = new PmsSkuSaleAttrValue(); //sku的销售属性
       //sku的会员价格
        List<SmsMemberPriceAddDTO>smsMemberPriceAddDTOList=new ArrayList<>();

        //sku的打折信息
        List<SmsSkuLadderAddDTO>smsSkuLadderAddDTOList=new ArrayList<>();

        //sku的满减信息
        List<SmsSkuFullReductionAddDTO>smsSkuFullReductionAddDTOS=new ArrayList<>();
        count = 0;
        for (Skus skus : skusList) {
            pmsSkuInfo.setBrandId(spuInfoVO.getBrandId());
            pmsSkuInfo.setCatalogId(spuInfoVO.getCatalogId());
            pmsSkuInfo.setPrice(skus.getPrice());
            pmsSkuInfo.setSaleCount(0L);
            if (count == 0) {
                pmsSkuInfo.setSkuDefaultImg(skus.getImages().get(0));
            }
            pmsSkuInfo.setSkuDefaultImg("");
            pmsSkuInfo.setSkuName(skus.getSkuName());
            pmsSkuInfo.setSkuSubtitle(skus.getSkuSubtitle());
            pmsSkuInfo.setSkuTitle(skus.getSkuTitle());
            pmsSkuInfo.setSpuId(pmsSpuInfo.getId());
            pmsSkuInfoMapper.insert(pmsSkuInfo);
            //3 新增商品图片 pms_sku_images

            List<String> imagesList = skus.getImages();
            //获得每一个图片
            int index = 0;
            for (String s : imagesList) {
                if (index == 0) {
                    pmsSkuImages.setDefaultImg(1);
                }
                pmsSkuImages.setImgSort(0);
                pmsSkuImages.setImgUrl(s);
                pmsSkuImages.setSkuId(pmsSkuInfo.getId());
                pmsSkuImagesMapper.insert(pmsSkuImages);

                index++;
            }

            //pms_sku_sale_attr_value 商品销售属性
            List<Attr> saleAttrsList = skus.getAttr();
            for (Attr attr : saleAttrsList) {
                pmsSkuSaleAttrValue.setAttrId(attr.getAttrId());
                pmsSkuSaleAttrValue.setAttrName(attr.getAttrName());
                pmsSkuSaleAttrValue.setAttrValue(attr.getAttrValue());
                pmsSkuSaleAttrValue.setAttrSort(0);
                pmsSkuSaleAttrValue.setSkuId(pmsSkuInfo.getId());
                pmsSkuSaleAttrValueMapper.insert(pmsSkuSaleAttrValue);
            }
            count++; //计数器
            //每个sku的会员价格
            List<MemberPrice> memberPriceList = skus.getMemberPrice();

            for (MemberPrice pricePrice : memberPriceList) {
                SmsMemberPriceAddDTO smsMemberPriceAddDTO = new SmsMemberPriceAddDTO();
                smsMemberPriceAddDTO.setAddOther((short) 0);
                smsMemberPriceAddDTO.setMemberLevelId(pricePrice.getId());
                smsMemberPriceAddDTO.setMemberLevelName(pricePrice.getName());
                smsMemberPriceAddDTO.setMemberPrice(pricePrice.getPrice());
                smsMemberPriceAddDTO.setSkuId(pmsSkuInfo.getId());
                smsMemberPriceAddDTOList.add(smsMemberPriceAddDTO);
            }
            //每个Sku的打折信息
            SmsSkuLadderAddDTO smsSkuLadderAddDTO = new SmsSkuLadderAddDTO();
            smsSkuLadderAddDTO.setAddOther((short) 0);
            smsSkuLadderAddDTO.setDiscount(skus.getDiscount());
            smsSkuLadderAddDTO.setFullCount(skus.getFullCount());
            smsSkuLadderAddDTO.setPrice(skus.getPrice());
            smsSkuLadderAddDTO.setSkuId(pmsSkuInfo.getId());
            //封装进打折集合
            smsSkuLadderAddDTOList.add(smsSkuLadderAddDTO);

            //每个sku的满减信息
            SmsSkuFullReductionAddDTO smsSkuFullReductionAddDTO =
                    new SmsSkuFullReductionAddDTO();
            smsSkuFullReductionAddDTO.setAddOther((short) 0);
            smsSkuFullReductionAddDTO.setFullPrice(skus.getFullPrice());
            smsSkuFullReductionAddDTO.setReducePrice(skus.getReducePrice());
            smsSkuFullReductionAddDTO.setSkuId(pmsSkuInfo.getId());
            //塞入集合
            smsSkuFullReductionAddDTOS.add(smsSkuFullReductionAddDTO);

        }
        //封装参数
        SmsSpuAddDTO smsSpuAddDTO=new SmsSpuAddDTO();
        //封装积分参数
        SmsSpuBoundsAddDTO smsSpuBoundsAddDTO=new SmsSpuBoundsAddDTO();
        //前端传入的积分信息
        Bounds bounds = spuInfoVO.getBounds();
        smsSpuBoundsAddDTO.setBuyBounds(bounds.getBuyBounds());
        smsSpuBoundsAddDTO.setGrowBounds(bounds.getGrowBounds());
        smsSpuBoundsAddDTO.setSpuId(pmsSpuInfo.getId());
        //商品的成长积分购买积分
        smsSpuAddDTO.setSmsSpuBoundsAddDTO(smsSpuBoundsAddDTO);
        //商品的会员价格
        smsSpuAddDTO.setSmsMemberPriceAddDTOList(smsMemberPriceAddDTOList);
        //商品的折扣信息
        smsSpuAddDTO.setSmsSkuLadderAddDTOList(smsSkuLadderAddDTOList);
        //商品的满减信息
        smsSpuAddDTO.setSmsSkuFullReductionAddDTOList(smsSkuFullReductionAddDTOS);
        //封装参数
        Result result = smsSpuFeignClient.saveSmsSpu(smsSpuAddDTO);
        if (result.getCode() == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
            throw  new HttpException(20003,500);
        }
        return  true;



    }

}
